import asyncio
import logging
import os

import pandas as pd
import requests

from .crawler_util import *


def init_loging_config():
    level = logging.INFO
    logging.basicConfig(
        filename='log',
        level=level,
        format="%(asctime)s %(name)s %(levelname)s %(message)s ",
        datefmt='%Y-%m-%d  %H:%M:%S'
    )
    _logger = logging.getLogger("xhs")
    _logger.setLevel(level)
    return _logger

logger = init_loging_config()


async def save_to_excel(file_name: str, data_list: list, columns: list):
    """
    保存在表格xlsx文件中
    Args:
        data_list: list
    Returns:
        None
    """
    lock = asyncio.Lock()
    # 将data_list转换为DataFrame
    df = pd.DataFrame(data_list, columns=columns)

    # 保存到Excel之前，下载并保存图片
    save_folder = 'images'  # 图片保存文件夹
    if 'image_url' in df and 'image_path' not in df:
        df['image_path'] = df['image_url'].apply(
            lambda url: download_image(url, save_folder))

    async with lock:
        # 检查文件是否存在
        if os.path.exists(file_name):
            # 删除文件
            os.remove(file_name)
            print(f"文件 {file_name} 已删除")
        else:
            print(f"文件 {file_name} 不存在")

        # 保存DataFrame为Excel文件
        try:
            await df.to_excel(file_name, index=False, engine='xlsxwriter')
            # df.to_excel(file_name, index=False)
        except Exception as e:
            logger.error(f"[save_to_excel] {e}")


def download_image(url, save_folder):
    """
    下载图片并保存到指定文件夹
    Args:
        url: str, 图片地址
        save_folder: str, 保存文件夹路径
    Returns:
        str, 保存的文件路径
    """
    if not os.path.exists(save_folder):
        os.makedirs(save_folder)

    try:
        response = requests.get(url)
        if response.status_code == 200:
            file_path = os.path.join(save_folder, os.path.basename(url))
            with open(file_path, 'wb') as f:
                f.write(response.content)
            return file_path
        else:
            return None
    except Exception as e:
        print(f"下载图片 {url} 失败: {e}")
        return None
    

